package com.example.widget_lib.widget.taperchart;

import com.example.widget_lib.bean.TaperChartBean;
import com.example.widget_lib.callback.ScrollMoveListener;
import com.example.widget_lib.scroller.AutoScroller;
import com.example.widget_lib.utils.LogUtil;
import com.example.widget_lib.utils.PxUtil;
import com.example.widget_lib.utils.Util;
import com.example.widget_lib.widget.touch.GestureDetector;
import ohos.agp.components.*;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class HorTaperChart extends Component implements Component.DrawTask, Component.TouchEventListener, ComponentTreeObserver.ScrollChangedListener {
    private final String TAG = this.getClass().getSimpleName();
    // 保留小数点后两位
    private static final DecimalFormat pointFormat = new DecimalFormat("#.##");
    public static final int[] COLORS = {
            Color.argb(153, 101, 226, 175), // 绿色
            Color.argb(153, 255, 196, 0), // 黄色
            Color.argb(153, 88, 181, 250), // 蓝色
    };
    private static final String ZERO = "0";
    /**
     * 最大值的偏移系数，能让y轴比最大值长点
     */
    private static final float MAX_COF = 0.1f;

    /**
     * 数据为空显示的文案
     */
    private static final String NOT_DATA = "暂无统计数据";

    /**
     * x轴贝塞尔曲线的控制点的y偏移量
     */
    private static final int QUAD_Y_SPACE = 40;
    /**
     * 滑动方向判定阈值
     */
    private static final int SCROLL_MIN_DISTANCE = 12;

    private Context mContext;
    // 文字大小
    private int mTextSize;
    // x轴图形相交的距离
    private int mInterSpace = 30;

    // 画布的宽高
    private int mCanvasW, mCanvasH;

    private Paint mPaint;
    // 坐标系画笔
    private Paint mAxisPaint;
    // 文字画笔
    private Paint mTextPaint;
    // 数据为空的画笔
    private Paint mNullPaint;
    // 控制点画笔
    private Paint mPointPaint;
    // 测量线画笔
    private Paint mLinePaint;
    // 图形宽度
    private float mLabelWidth = 200;
    // x轴贝塞尔曲线的控制点的x偏移量
    private float mQuadXSpace = 68;
    // 控制点偏移量的误差值
    private int mQuadOffset;
    // 图形在坐标轴内的左右偏移量
    private float mOffLeft = 0;
    private float mOffBtm = 36;
    // y轴上的值和坐标轴之间的间距
    private int mLeftAxisLabelMargin;
    // 是否绘制峰值顶尖值，默认false
    private boolean mIsDrawTopValue;
    // 数据总值
    private float mTotalValue;
    // y轴最大值
    private float y_max = 5;
    // y轴刻度集合
    private List<String> mYAxisList;
    private List<String> mXValues;
    private List<Float> mYValues;
    // 统计点对象集合
    private List<TaperChartBean> mList;
    // y轴最长label
    private String mYMaxStr;
    // y轴最长label的长度值
    private float mYMaxStrW;
    // y轴最长label的高度值
    private float mYMaxStrH;
    // x轴标签总数
    private int mXAxisCount = 0;

    // 手势相关
    /**
     * 手势状态：默认
     */
    public static final int SCROLL_STATE_IDLE = 0;
    /**
     * 手势状态：滑动中
     */
    public static final int SCROLL_STATE_DRAGGING = 1;
    /**
     * 手势状态：惯性滑动中
     */
    public static final int SCROLL_STATE_SETTING = 2;
    private int mScrollState = SCROLL_STATE_IDLE;

    // 滚动控制器
    private VelocityDetector mVelocityTracker;
    private int mMinFlingVelocity;
    private int mMaxFlingVelocity;
    private ScrollHelper mScroller;
    private int mLastFlingX;

    //顶部y值
    private int topY = 0;


    private float downX = 0f, downY = 0f;
    private float mOffsetX;
    private float flingX = 0;
    private float mTaperOffsetX; // 图形的偏移量
    private AutoScroller autoScroller;

    public HorTaperChart(Context context) {
        this(context, null);
    }

    public HorTaperChart(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public HorTaperChart(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        addDrawTask(this);
        setTouchEventListener(this);
        getComponentTreeObserver().addScrolledListener(this::onScrolled);
        autoScroller = new AutoScroller();
        autoScroller.setListener(new ScrollMoveListener() {
            @Override
            public void fling(int offsetX, int offsetY) {
                mOffsetX += (float) offsetX;
                float endTaperW = getEndTaperW();
                LogUtil.loge(TAG, "mOffsetX: " + mOffsetX + " flingX: " + flingX);
                if (Math.abs(mOffsetX) > endTaperW && flingX < 0) {
                    mOffsetX = -endTaperW;
                }
                if (Math.abs(mOffsetX) <= SCROLL_MIN_DISTANCE && flingX > 0) {
                    mOffsetX = 0;
                }
                invalidate();
            }
        });
        init(context);
    }

    @Override
    public void release() {
        super.release();
        getComponentTreeObserver().removeScrolledListener(this);
        if (mVelocityTracker != null) {
            mVelocityTracker.clear();
            mVelocityTracker = null;
        }
    }

    private void init(Context context) {
        mContext = context;
        mOffBtm = PxUtil.vp2px(18);
        mQuadOffset = (int) PxUtil.vp2px(5);
        mInterSpace = (int) PxUtil.vp2px(24);
        mLabelWidth = PxUtil.vp2px(98);
        mLeftAxisLabelMargin = (int) PxUtil.vp2px(4f);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(new Color(Color.argb(153, 255, 196, 0)));
        mPaint.setStrokeWidth(6);

        mAxisPaint = new Paint();
        mAxisPaint.setAntiAlias(true);
        mAxisPaint.setColor(new Color(Color.rgb(149, 199, 255)));
        mAxisPaint.setStrokeWidth(PxUtil.vp2px(0.5f));

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(new Color(Color.rgb(153, 153, 153)));

        mTextPaint.setTextSize((int) PxUtil.fp2px(10));
//        mTextPaint.setTextAlign(Paint.Align.LEFT);

        mNullPaint = new Paint();
        mNullPaint.setAntiAlias(true);
        mNullPaint.setColor(new Color(Color.rgb(200, 200, 200)));
        mNullPaint.setTextSize((int) PxUtil.fp2px(12f));

        mPointPaint = new Paint();
        mPointPaint.setAntiAlias(true);
        mPointPaint.setColor(Color.RED);
        mPointPaint.setStrokeWidth(10);
        mPointPaint.setStyle(Paint.Style.FILLANDSTROKE_STYLE);

        mLinePaint = new Paint();
        mLinePaint.setAntiAlias(true);
        mLinePaint.setStyle(Paint.Style.FILL_STYLE);
        mLinePaint.setStrokeWidth(PxUtil.vp2px(0.5f));
        mLinePaint.setColor(Color.RED);

        mYAxisList = new ArrayList<>(6);
        mList = new ArrayList<>(6);
        mXValues = new ArrayList<>(6);
        mYValues = new ArrayList<>(6);

//        final ViewConfiguration vc = ViewConfiguration.get(mContext);
//        mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
//        mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();

        mScroller = new ScrollHelper();
    }

    public void offSetXy(float xy) {
        mOffLeft = xy;
        invalidate();
    }

    /**
     * 设置空数据
     */
    public void setEmpty() {
        setData(null, null);
    }

    /**
     * 清空数据
     */
    public void clearData() {
        setEmpty();
    }

    /**
     * 填充图表数据
     *
     * @param xValues
     * @param yValues
     */
    public void setData(List<String> xValues, List<Float> yValues) {
        mTotalValue = 0;
        y_max = 0;
        mXValues.clear();
        mYValues.clear();

        if (Util.isEmpty(xValues) || Util.isEmpty(yValues)) { // 暂无数据
            invalidate();
            return;
        }
        mXValues = xValues;
        mYValues = yValues;
        mXAxisCount = mYValues.size();
        for (int i = 0; i < mXAxisCount; i++) {
            float y = mYValues.get(i);
            y_max = Math.max(y_max, y);
            mTotalValue = mTotalValue + y;
        }
        autoCalcYAxisMax();
        invalidate();
    }

    /**
     * 自动计算y轴最大值(对实际的最大值做处理)
     */
    private void autoCalcYAxisMax() {
        if (y_max < 10) {
            if (y_max <= 5) {
                y_max = 5;
            } else {
                y_max = 10;
            }
        } else {
            if (y_max % 10 != 0) {
                y_max = y_max + (10 - y_max % 10);
            }
        }
        y_max = y_max + y_max * MAX_COF;
    }

    /**
     * 数据为空的时候，绘制文案
     *
     * @param canvas
     */
    private void drawEmptyData(Canvas canvas) {
        int canvasW = getWidth();
        int canvasH = getHeight();
        int emptyTxtW = Util.getTextWidth(NOT_DATA, mNullPaint);
        int emptyTxtH = Util.getTextHeight(NOT_DATA, mNullPaint);
        // 画文字的时候，y值是文字的底线
        canvas.drawText(mNullPaint, NOT_DATA, canvasW / 2 - emptyTxtW / 2, canvasH / 2 + emptyTxtH / 2 - PxUtil.vp2px(1.5f));
    }

    /**
     * 绘制坐标系
     *
     * @param canvas
     */
    private void drawAxis(Canvas canvas) {
        // 刻度间的间距
        int yCount = mYAxisList.size();
        // y坐标轴的底部值
        float yAxisBtm = mCanvasH - mOffBtm;
        float h = (yAxisBtm - mYMaxStrH * 2) / yCount;
        for (int i = 0; i < yCount; i++) {
            String yLabel = mYAxisList.get(i);
            float yLabelW = Util.getTextWidth(yLabel, mTextPaint);
            // 绘制y轴刻度值(刻度右对齐相对y轴)
            canvas.drawText(mTextPaint, yLabel, mYMaxStrW - yLabelW, mYMaxStrH + h * i + mOffBtm);
        }
        // 绘制0刻度(刻度右对齐相对y轴)
        float yZeroStrW = Util.getTextWidth(ZERO, mTextPaint);
        canvas.drawText(mTextPaint, ZERO, mYMaxStrW - yZeroStrW, yAxisBtm);
        // 还原默认长度
        float axisL = mYMaxStrW + mLeftAxisLabelMargin;
        // 绘制x轴
        Point startPointX = new Point(axisL, yAxisBtm);
        Point endPointX = new Point(mCanvasW, yAxisBtm);
        canvas.drawLine(startPointX, endPointX, mAxisPaint);
        // 绘制y轴
        Point startPointY = new Point(axisL, mOffBtm);
        Point endPointY = new Point(axisL, yAxisBtm);
        canvas.drawLine(startPointY, endPointY, mAxisPaint);
    }

    private float mXAxisTxt_Y;

    public void setXAxisTxt_Y(float xAxisTxt_Y) {
        mXAxisTxt_Y = xAxisTxt_Y;
    }

    public float getXAxisTxt_Y() {
        return mXAxisTxt_Y;
    }

    private boolean mIsShowDebug = false;

    public void isShowDebugView(boolean isShowDebug) {
        mIsShowDebug = isShowDebug;
    }

    /**
     * 绘制x轴label
     *
     * @param canvas
     */
    private void drawLabel(Canvas canvas) {
        float yAxisBtm = mCanvasH - mOffBtm;
        // x轴label相对x轴的偏移量，间距
        int offset = (int) PxUtil.vp2px(1);
        int valueH = Util.getTextHeight(mXValues.get(0), mTextPaint);
        // 绘制x轴刻度值
        float xAxisTxt_Y = yAxisBtm + valueH + offset;
        setXAxisTxt_Y(xAxisTxt_Y);

        String key;
        float xOffset;
        for (int i = 0; i < mXAxisCount; i++) {
            key = mXValues.get(i);
            int valueW = Util.getTextWidth(key, mTextPaint);
            if (i == 0) {
                xOffset = start_x + mLabelWidth / 2 - valueW / 2;
            } else {
                xOffset = start_x + mLabelWidth * i - mInterSpace * i // 算出下一个点的起始点
                        + (mLabelWidth / 2 - valueW / 2); // 文字居中
            }
            canvas.drawText(mTextPaint, key, xOffset, xAxisTxt_Y);
        }
    }

    private void calcStartXOffset() {
        // 重新计算图形宽度
        int chartW = (int) (getWidth() - mYMaxStrW - mLeftAxisLabelMargin - mLinePaint.getStrokeWidth());
        mLabelWidth = (chartW / 2 + mInterSpace) / 2;
        start_x = (int) (mOffLeft + mYMaxStrW + mLeftAxisLabelMargin + mLinePaint.getStrokeWidth());
        mQuadXSpace = mLabelWidth / 2 - mQuadOffset;
    }

    private int start_x = 0;

    private void drawData(Canvas canvas) {
        // 单个数值对应的坐标高度
        float oneH = (mCanvasH - mOffBtm - mPaint.getStrokeWidth()) / y_max;
        Point pf;

        if (Util.isNotEmpty(mList)) {
            mList.clear();
        }

        String key;
        float value;
        float pf_y = mCanvasH - mOffBtm;

        for (int i = 0; i < mXAxisCount; i++) {
            key = mXValues.get(i);
            value = mYValues.get(i);
            float dataPAxisH = mCanvasH - (value * oneH);
            pf = new Point();
            pf.modify(start_x + mLabelWidth * i - mInterSpace * i, pf_y);
            drawGraph(canvas, pf, dataPAxisH, COLORS[2], key, value);
        }
    }

    /**
     * 绘制图形
     *
     * @param canvas
     * @param pf         开始绘制的点坐标
     * @param topY       顶部y值
     * @param paintColor 画笔颜色
     * @param xValue     对应的数据值 x
     * @param yValue     对应的数据值 y
     */
    private void drawGraph(Canvas canvas, Point pf, float topY, int paintColor, String xValue, float yValue) {
        // 设置画笔颜色
        mPaint.setColor(new Color(paintColor));
        // 直接参与画图的path
        Path path = new Path();
        // 图形中心点x轴值
        float centerX = pf.getPointX() + mLabelWidth / 2;

        // 左侧控制点
        Point pfL = new Point();
        pfL.modify(pf.getPointX() + mQuadXSpace, pf.getPointY() - QUAD_Y_SPACE);

        if (topY >= pfL.getPointY()) { // 极端场景处理：数据值的y坐标>=控制点的y坐标
            if (topY >= mCanvasH - mOffBtm) { // 到底了，也就是数据为0的情况
                if (yValue > 0f) { // 总得有点东西显示吧
                    // 控制点做调整
                    pfL.modify(pfL.getPointX(), mCanvasH - mOffBtm - QUAD_Y_SPACE / 5);
                    topY = pfL.getPointY() - QUAD_Y_SPACE / 5;
                } else {
                    pfL.modify(pfL.getPointX(), mCanvasH - mOffBtm);
                    topY = pfL.getPointY();
                }
            } else {
                topY = topY - mOffBtm;
                pfL.modify(pfL.getPointX(), topY + (mCanvasH - mOffBtm - pfL.getPointY()) / 2);
            }
        }

        TaperChartBean bean = new TaperChartBean();
        RectFloat rectF = new RectFloat(pf.getPointX(), topY, pf.getPointX() + mLabelWidth, pf.getPointY());
        bean.setRectF(rectF);
        bean.setxValue(xValue);
        bean.setyValue(yValue);
        mList.add(bean);


        Path pathL = new Path();
        pathL.moveTo(pf.getPointX(), pf.getPointY());
        pathL.quadTo(pfL.getPointX(), pfL.getPointY(), centerX, topY);
        pathL.lineTo(centerX, pf.getPointY());

        Point pfR = new Point();
        pfR.modify(pf.getPointX() + mLabelWidth - mQuadXSpace, pfL.getPointY());
        // 右边图形路径
        Path pathR = new Path();
        pathR.moveTo(pf.getPointX() + mLabelWidth, pf.getPointY());
        pathR.quadTo(pfR.getPointX(), pfR.getPointY(), centerX, topY);
        pathR.lineTo(centerX, pf.getPointY());

        // path路径组合
        path.addPath(pathL);
        path.addPath(pathR);
        canvas.drawPath(path, mPaint);


        drawTopValue(canvas, yValue, topY, centerX);


        if (mIsShowDebug) {
            // 左 - 控制点
            canvas.drawPoint(pf.getPointX() + mQuadXSpace, pf.getPointY() - QUAD_Y_SPACE, mPointPaint);
            // 右 - 控制点
            canvas.drawPoint(pf.getPointX() + mLabelWidth - mQuadXSpace, pf.getPointY() - QUAD_Y_SPACE, mPointPaint);
            //绘制测量线，便于观察绘制的准确性

            canvas.drawLine(new Point(centerX, topY - PxUtil.vp2px(5)), new Point(centerX, pf.getPointY()), mLinePaint);
            // 绘制高度测量线，便于观察绘制的准确性
            mPaint.setStrokeWidth(1.5f);
            Point startPoint = new Point(mYMaxStrW + mLeftAxisLabelMargin + mPaint.getStrokeWidth(), topY);
            Point endPoint = new Point(centerX, topY);
            canvas.drawLine(startPoint, endPoint, mPaint);
        }
    }

    /**
     * 绘制峰值头部数值
     *
     * @param canvas
     * @param yValue
     * @param topY
     * @param centerX
     */
    private void drawTopValue(Canvas canvas, float yValue, float topY, float centerX) {
        if (mIsDrawTopValue) {
            String text = pointFormat.format(yValue);
            canvas.drawText(mTextPaint, text, centerX - Util.getTextWidth(text, mTextPaint) / 2, topY - PxUtil.vp2px(2));
        }
    }


    /**
     * 计算y轴刻度
     */
    private void calcYAxisScale() {
        int count = 5;
        mYAxisList.clear();
        // y轴上刻度间的间距
        float yAxisSpace = y_max / count;
        for (int i = 0; i < count; i++) {
            float yScale = y_max - i * yAxisSpace;
            mYAxisList.add((int) yScale + "");
        }
        mYMaxStr = mYAxisList.get(0);
        mYMaxStrW = Util.getTextWidth(mYMaxStr, mTextPaint);
        mYMaxStrH = Util.getTextHeight(mYMaxStr, mTextPaint);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (Util.isEmpty(mXValues) || Util.isEmpty(mYValues)) {
            drawEmptyData(canvas);
            return;
        }
        topY = (int) PxUtil.vp2px(getTop());
        mCanvasW = getWidth();
        mCanvasH = getHeight();
        LogUtil.loge(TAG, "view的宽度-->onDraw: canvasW = " + mCanvasW + "->canvasH = " + mCanvasH + "->mOffsetX = " + mOffsetX);

        calcYAxisScale();
        calcStartXOffset();

        // 1.绘制坐标轴
        drawAxis(canvas);
        // 2.裁剪图形显示区域
        float left = mYMaxStrW + mLeftAxisLabelMargin;
        RectFloat f = new RectFloat(left, 0, mCanvasW, mCanvasH);
        canvas.clipRect(f, Canvas.ClipOp.INTERSECT);
        // 3.通过手势滑动图形
        canvas.translate(mOffsetX, 0);
        // 4.绘制x轴上的label
        drawLabel(canvas);
        // 5.绘制图形数据
        drawData(canvas);
    }

    public float getOffsetX() {
        return mOffsetX;
    }

    public void setOffsetX(float offsetX) {
        mOffsetX = offsetX;
        invalidate();
    }

    /**
     * 第一张图形的坐标值
     *
     * @return float
     */
    private float getFirstTaperW() {
        return mLabelWidth + mOffLeft;
    }

    public void setInterSpace(int mInterSpace) {
        this.mInterSpace = mInterSpace;
    }

    public void setDrawTopValue(boolean mIsDrawTopValue) {
        this.mIsDrawTopValue = mIsDrawTopValue;
    }

    /**
     * 最后一张图形的坐标值
     *
     * @return float
     */
    private float getEndTaperW() {
        return start_x + (mLabelWidth * mXAxisCount) - (mInterSpace * (mXAxisCount - 1)) - getWidth();
    }


    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityDetector.obtainInstance();
        }
        boolean eventAddedToVelocityTracker = false;
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN: {
                downX = (int) event.getPointerPosition(0).getX();
                downY = (int) event.getPointerPosition(0).getY() - topY;
                mTaperOffsetX = mOffsetX;
            }
            break;
            case TouchEvent.POINT_MOVE: {
                float moveX = event.getPointerPosition(0).getX();
                mOffsetX = mTaperOffsetX + moveX - downX;
                flingX = moveX - downX;
                if (moveX - downX > SCROLL_MIN_DISTANCE) { // 向右滑动,禁止第一张图超出初始值
                    if (mOffsetX > 0) {
                        mOffsetX = 0;
                        flingX = 0;
                    }
                } else if (moveX - downX < -SCROLL_MIN_DISTANCE) { // 向左滑动，禁止最后一张图超出初始值
                    // 最后一张图形的坐标值
                    float endTaperW = getEndTaperW();
                    if (Math.abs(mOffsetX) > endTaperW) {
                        mOffsetX = -endTaperW;
                        flingX = 0;
                    }
                    LogUtil.loge(TAG, "mOffsetX = " + mOffsetX + "->endTaperW = " + endTaperW);
                }
                invalidate();
                break;
            }
            case TouchEvent.PRIMARY_POINT_UP: {
                LogUtil.loge(TAG, "Up => mOffsetX = " + mOffsetX + " flingX: " + flingX);
                mVelocityTracker.addEvent(event);
                eventAddedToVelocityTracker = true;
                autoScroller.start((int) -flingX, 0);
                /*mVelocityTracker.calculateCurrentVelocity(1000, mMaxFlingVelocity, 0);
                LogUtil.loge(TAG, "mMaxFlingVelocity: " + mMaxFlingVelocity);
                float xVelocity = mVelocityTracker.getHorizontalVelocity();
                if (Math.abs(xVelocity) < mMinFlingVelocity) {
                    xVelocity = 0F;
                } else {
                    xVelocity = Math.max(-mMaxFlingVelocity, Math.min(xVelocity, mMaxFlingVelocity));
                }
                if (xVelocity != 0) {
                    // 将速度值反应到滚动器上
                    LogUtil.loge("autoScroller => start => xVelocity:" + xVelocity);
                    autoScroller.start((int) xVelocity, 0);
//                    onFling((int) xVelocity);
                } else {
                    LogUtil.loge("autoScroller => empty");
                    mScrollState = SCROLL_STATE_IDLE;
                }*/
                resetTouch();
                break;
            }
            case TouchEvent.CANCEL: {
                resetTouch();
            }
            break;
        }
        if (!eventAddedToVelocityTracker) {
            mVelocityTracker.addEvent(event);
        }
        return true;
    }

    private void resetTouch() {
        if (mVelocityTracker != null) {
            mVelocityTracker.clear();
        }
    }

    public void onFling(int velocityX) {
        mLastFlingX = 0;
        mScrollState = SCROLL_STATE_SETTING;
        mScroller.doFling(0, 0, velocityX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
        invalidate();
    }

    @Override
    public void onScrolled() {
        if (mScroller.isOverScrolled()) {
            int x = mScroller.getFlingVelocityX();
            int dis = x - mLastFlingX;
            mLastFlingX = x;
            // 更新偏移量，达到移动效果
            mOffsetX += dis;
            LogUtil.loge("computeScroll", "dis = " + dis + "->mOffsetX = " + mOffsetX + "->mTaperOffsetX = " + mTaperOffsetX + "->currX = " + x);
            // 边界超出限制
            if (x < 0) { // 左滑
                float endTaperW = getEndTaperW();
                if (Math.abs(mOffsetX) > endTaperW) {
                    mOffsetX = -endTaperW;
                }
            } else if (x > 0) { // 右滑
                if (mOffsetX > 0) {
                    mOffsetX = 0;
                }
            }
            invalidate();
        }
    }

    public List<TaperChartBean> getList() {
        return mList;
    }


    // 自定义动画插值器 f(x) = (x-1)^5 + 1
//    private static final Interpolator interpolator = input -> {
//        input -= 1.0f;
//        return input * input * input * input * input + 1.0f;
//    };


}
